import math


def affine_cipher_encrypt(plaintext, a, b):
    ciphertext = []
    # 验证a是否与26互质
    if math.gcd(a, 26) != 1:
        raise ValueError("参数a必须与26互质")
    # 验证b是否在0-25范围内
    if not 0 <= b < 26:
        raise ValueError("参数b必须是0-25之间的整数")

    for char in plaintext.upper():
        if char.isalpha():
            # 字母转换为0-25的数字
            num = ord(char) - ord('A')
            # 加密公式：C = (a*P + b) mod 26
            encrypted_num = (a * num + b) % 26
            ciphertext.append(chr(encrypted_num + ord('A')))
        else:
            # 保留非字母字符
            ciphertext.append(char)
    return ''.join(ciphertext)


def affine_cipher_decrypt(ciphertext, a, b):
    plaintext = []
    # 计算a的模逆元
    try:
        inv_a = pow(a, -1, 26)
    except ValueError:
        raise ValueError("参数a与26不互质，无法解密")
    # 验证b是否在0-25范围内
    if not 0 <= b < 26:
        raise ValueError("参数b必须是0-25之间的整数")

    for char in ciphertext.upper():
        if char.isalpha():
            num = ord(char) - ord('A')
            # 解密公式：P = inv_a*(C - b) mod 26
            decrypted_num = (inv_a * (num - b)) % 26
            plaintext.append(chr(decrypted_num + ord('A')))
        else:
            plaintext.append(char)
    return ''.join(plaintext)


if __name__ == "__main__":
    a = 5  # 必须与26互质（如3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25）
    b = 8  # 必须是0-25之间的整数
    plaintext = "HELLOWORLD"

    encrypted = affine_cipher_encrypt(plaintext, a, b)
    print(f"加密结果: {encrypted}")  # 输出：QHXYXOXYHJ

    decrypted = affine_cipher_decrypt(encrypted, a, b)
    print(f"解密结果: {decrypted}")  # 输出：HELLOWORLD